package co.dreamapps.dodoattack.model;

import java.io.IOException;
import org.andengine.audio.sound.Sound;
import org.andengine.audio.sound.SoundFactory;
import org.andengine.engine.Engine;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.JumpModifier;
import org.andengine.entity.modifier.IEntityModifier.IEntityModifierListener;
import org.andengine.entity.scene.Scene;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.opengl.texture.TextureManager;
import org.andengine.opengl.texture.TextureOptions;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlas;
import org.andengine.opengl.texture.atlas.bitmap.BitmapTextureAtlasTextureRegionFactory;
import org.andengine.opengl.texture.region.ITiledTextureRegion;
import org.andengine.opengl.vbo.VertexBufferObjectManager;
import org.andengine.util.modifier.IModifier;
import android.content.Context;
import android.util.Log;

public class Dodo {	

	/**
	 * Constants
	 */
	final long[] DURATION_FRAME_NORMAL = { 100, 100, 150, 125, 100, 100 };

	/**
	 * Animation
	 */
	private ITiledTextureRegion texturaAnimada;
	private BitmapTextureAtlas atlasAnimacion;
	private AnimatedSprite spriteAnimado;
	private JumpModifier jumpModifier;
	private int jumpingTimes = 0;
	private int floor;
	private int windowWidth;
	private Boolean jumping;
	private int sentWhileNotMoving;

	/**
	 * Sound
	 */
	private Sound chickenSound;

	/**
	 * Connection
	 */
	private RoomManagerDodoGame roomManager;
	private boolean sendUpdates;
	
	/**
	 * Constructor
	 */
	public Dodo(RoomManagerDodoGame roomManager, int windowWidth, boolean sendUpdates) {
		this.roomManager = roomManager;
		this.windowWidth = windowWidth;
		this.sendUpdates = sendUpdates;
	}
	
	/**
	 * Methods
	 */
	public void onCreateResources(TextureManager textureManager, Engine engine, Context context) throws IOException {
		atlasAnimacion = new BitmapTextureAtlas(textureManager, 480, 344,TextureOptions.DEFAULT);
		texturaAnimada = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(atlasAnimacion, context,"dodoSecuencia.png", 0, 0, 3, 2);
		atlasAnimacion.load();
		try {
			chickenSound = SoundFactory.createSoundFromAsset(engine.getSoundManager(), context, "sonido/upChicken.mp3");
			chickenSound.setLooping(false);
		} catch (IOException e) {
			Log.e("Alejo", "IOException: Carga de audio");
		}
	}

	public void onCreateScene(VertexBufferObjectManager vertexBufferObjectManager, Scene scene, int x, int y) {
		this.floor = y;
		spriteAnimado = new AnimatedSprite(x, y, texturaAnimada, vertexBufferObjectManager);
		spriteAnimado.animate(DURATION_FRAME_NORMAL, 0, 5, true);
		scene.attachChild(spriteAnimado);
	}

	public void scream() {
		chickenSound.play();
	}

	public void jump() {
		if (jumpingTimes < 2) {
			if(sendUpdates) {
				roomManager.dodoJump(jumpingTimes, (int)spriteAnimado.getY(), true);
			}
			jumpingTimes ++;
			chickenSound.play();
			if(jumpModifier != null) {
				spriteAnimado.unregisterEntityModifier(jumpModifier);
			}
			jumpModifier = new JumpModifier(1, spriteAnimado.getX(), spriteAnimado.getX(), spriteAnimado.getY(), floor, -300, new IEntityModifierListener() {
				@Override
				public void onModifierStarted(
						IModifier<IEntity> pModifier, IEntity pItem) {
					if(jumpingTimes == 2) {
						long[] duracionFrame = { 60, 60, 60 };
						spriteAnimado.animate(duracionFrame, 2, 4, true);
					}
				}

				@Override
				public void onModifierFinished(
						IModifier<IEntity> pModifier, IEntity pItem) {
					jumpingTimes = 0;
					jumping = false;
					spriteAnimado.animate(DURATION_FRAME_NORMAL, 0, 5, true);
					roomManager.dodoJump(-1, (int)spriteAnimado.getY(), true);
				}
			});
			spriteAnimado.registerEntityModifier(jumpModifier);
			// Jumping Update Thread
			if(sendUpdates) {
				jumping = false;
				new Thread(new Runnable() {
					@Override
					public void run() {
						jumping = true;
						int jumpingIndex = jumpingTimes;
						while(jumping && jumpingIndex == jumpingTimes) {
							roomManager.dodoJump(-1, (int)spriteAnimado.getY(), false);
							try {Thread.sleep(250);} catch (Exception e) {}
						}
					}
				}).start();
			}
		}
	}

	public void jump(int jumpingTimes, int actualY) {
		this.spriteAnimado.setY(actualY);
		if(jumpingTimes != -1) {
			this.jumpingTimes = jumpingTimes;
			jump();
		}
	}

	public void setX(int x) {
		spriteAnimado.setX(x);
	}

	public void setY(int y) {
		spriteAnimado.setY(y);
	}

	public void setHorizontalMove(float x) {
		if(x < -1) {
			sentWhileNotMoving = 0;
			if(spriteAnimado.getX() > spriteAnimado.getWidth()) {
				if(x < -2) {
					if(x < -4)
						spriteAnimado.setX(spriteAnimado.getX()-10);
					else
						spriteAnimado.setX(spriteAnimado.getX()-7);
				} else
					spriteAnimado.setX(spriteAnimado.getX()-4);
				roomManager.dodoHorizontalMove((int) spriteAnimado.getX(), true);
			}
		} else if(x > 1) {
			sentWhileNotMoving = 0;
			if(spriteAnimado.getX() < windowWidth - spriteAnimado.getWidth()) {
				if(x > 2) {
					if(x > 4)
						spriteAnimado.setX(spriteAnimado.getX()+10);
					else
						spriteAnimado.setX(spriteAnimado.getX()+7);
				} else
					spriteAnimado.setX(spriteAnimado.getX()+4);
				roomManager.dodoHorizontalMove((int) spriteAnimado.getX(), true);
			}
		} else {
			if(sentWhileNotMoving < 3) {
				if(roomManager.dodoHorizontalMove((int) spriteAnimado.getX(), false)) {
					sentWhileNotMoving ++;
				}
			}
		}
	}
}
